package gja;

import java.awt.Color;
import java.util.Random;
import robocode.HitWallEvent;
import robocode.Robot;
import robocode.Rules;
import robocode.ScannedRobotEvent;

/**
 * Implements the ShootNScoot robot.
 * 
 * @author Jayson Gamiao
 */
public class ShootNScoot extends Robot {
  String markRobot; // Mark a robot as the primary target.

  /**
   * run: ShootNScoot's main run function. The main movement algorithm (aside from generating new
   * coordinates) is provided by the DwRotater robot found in the IBM Robocode article.
   */
  public void run() {
    // Set colors
    setBodyColor(Color.black);
    setGunColor(Color.black);
    setRadarColor(Color.black);
    setBulletColor(Color.red);
    setScanColor(Color.green);

    markRobot = null;

    while (true) {
      // Find a new firing position.
      double positionX = generateFiringPosition();
      double positionY = generateFiringPosition();

      // Find the coordinates of the robot.
      double myX = getX();
      double myY = getY();

      turnLeft(getHeading());

      if (myY < positionY) {
        // Fire gun before moving to a new position.
        turnGunRight(360);
        ahead(positionY - myY);
      }
      else {
        turnLeft(180);
        ahead(myY - positionY);
        turnLeft(180);
      }

      turnRight(90);

      if (myX < positionX) {
        // Fire gun before moving to a new position.
        turnGunRight(360);
        ahead(positionX - myX);
      }
      else {
        turnLeft(180);
        ahead(myX - positionX);
      }
      turnGunRight(360);
    }
  }

  /**
   * onScannedRobot: Fire at enemy robot with bullet power proportional to enemy distance.
   * 
   * @param enemy contains information about enemy robot.
   */
  public void onScannedRobot(ScannedRobotEvent enemy) {
    double fieldWidth = getBattleFieldWidth(); // fieldWidth is used to calculate optimal bullet
                                               // power.
    // Track the first enemy detected by radar.
    if (markRobot == null) {
      markRobot = enemy.getName();
    }
    // Only fire on a marked enemy robot.
    if (enemy.getName().equals(markRobot)) {
      if (enemy.getDistance() > fieldWidth / 2) {
        fire(1);
      }
      else if (enemy.getDistance() > fieldWidth / 4) {
        fire(2);
      }
      else {
        fire(Rules.MAX_BULLET_POWER);
      }
    }
    // Set markRobot back to null to allow for a new target.
    markRobot = null;
  }

  /**
   * onHitWall: Reverse 150 pixels when hitting a wall.
   * 
   * @param event signals a collision with a wall.
   */
  public void onHitWall(HitWallEvent event) {
    back(150);
    scan();
  }

  /**
   * generateFiringPosition: Generate a random integer that will determine the robot's firing
   * position.
   * 
   * @return a random integer between 0 and 1200.
   */
  public double generateFiringPosition() {
    double coordinate = 0.0;
    // Generate a random number with a seed given from the current system time.
    Random generator = new Random(System.currentTimeMillis());
    coordinate = generator.nextInt(1200);
    return coordinate;
  }
}